/*
 * @Author: ZephyrGao
 * @Date: 2024-02-27 16:41:35
 * @Description: axios tool
 * Copyright (c) 2024 by ZephyrGao, All Rights Reserved. 
 */
import { isMock } from '@/config/config';
import { useUserStore } from '@/store/core/useUserStore';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import MockAdapter from 'axios-mock-adapter';

/**
 * axios 工具类配置
 * @description: axios 工具类配置
 */
interface AxiosUtilOptions {
  baseURL?: string;
  timeout?: number;
  headers?: Record<string, string>;
  isMock?:boolean
  // 添加其他默认配置...
}

/**
 * axios 工具类
 * @description: axios 工具类
 */
class AxiosUtil {
  private axiosInstance: AxiosInstance;
  // mockAdapter 用这个可以不用写mock.js文件
  mockAdapter: MockAdapter | undefined;

  constructor(options: AxiosUtilOptions) {
    // 合并用户提供的配置和默认配置
    const defaultConfig: AxiosRequestConfig = {
      timeout: options.timeout || 5000,
      headers: options.headers || {},
      baseURL: options.baseURL || '',
      // 添加其他默认配置...
    };
    // 根据环境切换 baseURL 
    // console.log('baseURL :>> ', options.baseURL);
    if (options.baseURL) {
      defaultConfig.baseURL = options.baseURL;
    }
    this.axiosInstance = axios.create({ 
      ...defaultConfig,
    });

    // 创建 Mock Adapter
    /**
     * AxiosHelper.mockAdapter.onPost('/api/login', { username: 'demo', password: 'password' }).reply(200, {
        code: 200,
        message: 'Login successful1111',
        data: {
          token: 'mocked-token',
          username: 'demo',
        },
      });
      // 实际的请求
      AxiosHelper.post('/api/login', { username: 'demo', password: 'password' })
        .then(response => {
          console.log(response);
        })
        .catch(error => {
          console.error(error);
        });
     */
    if (isMock) {
      this.mockAdapter = new MockAdapter(this.axiosInstance);
    } 
    // 添加请求拦截器
    this.axiosInstance.interceptors.request.use(
      (config: InternalAxiosRequestConfig) => {
        // 可以在这里添加认证信息、设置请求头等 
        const userStore = useUserStore();
        const token = userStore.token    
		    if (token) {
          config.headers.Authorization = `Bearer ${token}`;
        }   
		    return config;   
      },
      (error: any) => {
        // 对请求错误做些什么
        return Promise.reject(error);
      }
    );

    // 添加响应拦截器
    this.axiosInstance.interceptors.response.use(
      // 请求成功
      response => response.status === 200 ? Promise.resolve(response) : Promise.reject(response),
      
      (error: any) => {
        const { data } = error;
        // 服务器状态码不是200的情况 
        // return Promise.reject(error);
        if (data) {
          // 请求已发出，但是不在2xx的范围 
          this.errorHandle(data.status, data.data.message);
          return Promise.reject(data);
        } else {
          // 处理断网的情况
          // eg:请求超时或断网时，更新state的network状态
          // network状态在app.vue中控制着一个全局的断网提示组件的显示隐藏
          // 关于断网组件中的刷新重新获取数据，会在断网组件中说明
          if (!window.navigator.onLine) {
            //  store.commit('changeNetwork', false);
          } else {
            return Promise.reject(error);
          }
        }
      }
    );

  }

  // 允许外部更改 baseURL
  updateBaseURL(newBaseURL: string): void {
    this.axiosInstance.defaults.baseURL = newBaseURL;
  }

  // 允许外部更改 timeout
  updateTimeout(newTimeout: number): void {
    this.axiosInstance.defaults.timeout = newTimeout;
  }

  // GET 请求
  async get<T>(url: string, params?: Record<string, any>): Promise<T> {
    const response: AxiosResponse<T> = await this.axiosInstance.get(url, { params });
    return response.data;
  }

  // POST 请求
  async post<T>(url: string, data?: Record<string, any>): Promise<T> {
    const response: AxiosResponse<T> = await this.axiosInstance.post(url, data);
    return response.data;
  }

  // PUT 请求
  async put<T>(url: string, data?: Record<string, any>): Promise<T> {
    const response: AxiosResponse<T> = await this.axiosInstance.put(url, data);
    return response.data;
  }

  // DELETE 请求
  async delete<T>(url: string): Promise<T> {
    const response: AxiosResponse<T> = await this.axiosInstance.delete(url);
    return response.data;
  }

  // PATCH 请求  
  async patch<T>(url: string, data?: Record<string, any>): Promise<T> {  
    const response: AxiosResponse<T> = await this.axiosInstance.patch(url, data);  
    return response.data;  
  }  

  // HEAD 请求 
  async head<T>(url: string, params?: Record<string, any>): Promise<T> {  
    const response: AxiosResponse<T> = await this.axiosInstance.head(url, { params });
    return response.data;
  }

  // OPTION 请求 
  async options<T>(url: string, params?: Record<string, any>): Promise<T> {  
    const response: AxiosResponse<T> = await this.axiosInstance.options(url, { params });
    return response.data;;
  }

  // 请求失败后的错误统一处理 
  errorHandle = (status :any, other :any) => { 

    // 状态 码判断
    switch (status) {
      // 401: 未登录状态，跳转登录页
      case 401:
        // toLogin();
        break;
      // 403 token过期
      // 清除token并跳转登录页
      case 403:
        // tip('登录过期，请重新登录');
        // localStorage.removeItem('token');
        // store.commit('loginSuccess', null);
        // setTimeout(() => {
        // 	toLogin();
        // }, 1000);
        break;
      // 404请求不存在
      case 404:
        // tip('请求的资源不存在'); 
        break;
      default:
        console.log(other);   
    }
  }
}

export default AxiosUtil;